Skip to content

[ES|QL] Add MATCH_PHRASE #127661

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

kderusso
Copy link
Member

@kderusso kderusso commented May 2, 2025

Adds MATCH_PHRASE support to ES|QL.

Some examples of how to use MATCH_PHRASE:

POST _query?format=txt
{
  "query": """
  FROM books METADATA _score
  | WHERE MATCH_PHRASE(title, "return of the king")
  | KEEP title, _score
  | SORT _score
  | LIMIT 5
  """
}

POST _query?format=txt
{
  "query": """
  FROM books METADATA _score
  | WHERE MATCH_PHRASE(title, "return of king", {"slop": 5})
  | KEEP title, _score
  | SORT _score
  | LIMIT 5
  """
}

POST _query?format=txt
{
  "query": """
  FROM books METADATA _score
  | WHERE MATCH_PHRASE(title, "return of king", {"analyzer": "whitespace"})
  | KEEP title, _score
  | SORT _score
  | LIMIT 5
  """
}

POST _query?format=txt
{
  "query": """
  FROM books METADATA _score
  | WHERE MATCH_PHRASE(title, "", {"zero_terms_query": "all"})
  | KEEP title, _score
  | SORT _score
  | LIMIT 5
  """
}

@kderusso kderusso force-pushed the kderusso/esql-match-phrase branch from dabef06 to 13ccda7 Compare May 6, 2025 19:32
@kderusso kderusso added :SearchOrg/Relevance Label for the Search (solution/org) Relevance team >enhancement labels May 7, 2025
@elasticsearchmachine
Copy link
Collaborator

Hi @kderusso, I've created a changelog YAML for you.


MatchPhrase can use <<esql-function-named-params,function named parameters>> to specify additional options for the
match_phrase query.
All <<query-dsl-match-query-phrase,match_phrase>> query parameters are supported.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: When I try to link to the correct doclink here, I get:

Invalid link key <<match-phrase-field-params,match_phrase query parameters>>


**Description**

Use `MATCH_PHRASE` to perform a [match_phrase query](/reference/query-languages/query-dsl/query-dsl-match-query.md#query-dsl-match-query-phrase) on the specified field. Using `MATCH_PHRASE` is equivalent to using the `match_phrase` query in the Elasticsearch Query DSL. MatchPhrase can be used on [text](/reference/elasticsearch/mapping-reference/text.md) fields, as well as other field types like keyword, boolean, or date types. MatchPhrase is not supported for [semantic_text](/reference/elasticsearch/mapping-reference/semantic-text.md) or numeric types. MatchPhrase can use [function named parameters](/reference/query-languages/esql/esql-syntax.md#esql-function-named-params) to specify additional options for the match_phrase query. All [match_phrase](/reference/query-languages/query-dsl/query-dsl-match-query.md#query-dsl-match-query-phrase) query parameters are supported. `MATCH_PHRASE` returns true if the provided query matches the row.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why we're picking up match query docs in the generated documentation here, we should be picking up query-dsl-match-query-phrase.md.

@kderusso kderusso marked this pull request as ready for review May 9, 2025 19:49
@kderusso kderusso requested review from ioanatia and carlosdelest May 9, 2025 19:49
@elasticsearchmachine elasticsearchmachine added Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) Team:SearchOrg Meta label for the Search Org (Enterprise Search) Team:Search - Relevance The Search organization Search Relevance team labels May 9, 2025
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-analytical-engine (Team:Analytics)

@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/search-eng (Team:SearchOrg)

@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/search-relevance (Team:Search - Relevance)

@kderusso kderusso requested review from afoucret and a team May 9, 2025 19:49
@@ -1,4 +1,7 @@
* [preview] [`KQL`](../../functions-operators/search-functions.md#esql-kql)
* [preview] [`MATCH`](../../functions-operators/search-functions.md#esql-match)
* [preview] [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to modify this file, because the function is just available in snapshot.
At most you can comment this one with a % as we do for the term function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented out, thanks

:::{include} ../_snippets/functions/layout/kql.md
:::

:::{include} ../_snippets/functions/layout/match.md
:::

:::{include} ../_snippets/functions/layout/match_phrase.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again I don't think we need this since the function is not available outside snapshots

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented out, thanks

Copy link
Contributor

@ioanatia ioanatia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are missing validation tests in VerifierTests for cases like:

  • what happens when match_phrase is used after STATS - this should fail with a validation error
  • what happens when we pass invalid options to match_phrase - same, we have a validation error
  • what happens when match_phrase receives a column as argument that is not a mapped field - again a validation error

there are other cases that we might need to test - please take a look at what we did for match in VerifierTests and add similar tests.

return new MatchPhraseQuery(source(), fieldName, queryAsObject(), matchPhraseQueryOptions());
}

public static String getNameFromFieldAttribute(FieldAttribute fieldAttribute) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a duplicate of:

public static String getNameFromFieldAttribute(FieldAttribute fieldAttribute) {
String fieldName = fieldAttribute.name();
if (fieldAttribute.field() instanceof MultiTypeEsField multiTypeEsField) {
// If we have multiple field types, we allow the query to be done, but getting the underlying field name
fieldName = multiTypeEsField.getName();
}
return fieldName;
}

Either use the Match one or move them both to another place, like FullTextFunction.

return fieldName;
}

public static FieldAttribute fieldAsFieldAttribute(Expression field) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a duplicate of:

public static FieldAttribute fieldAsFieldAttribute(Expression field) {
Expression fieldExpression = field;
// Field may be converted to other data type (field_name :: data_type), so we need to check the original field
if (fieldExpression instanceof AbstractConvertFunction convertFunction) {
fieldExpression = convertFunction.field();
}
return fieldExpression instanceof FieldAttribute fieldAttribute ? fieldAttribute : null;
}

Either use the Match one or move them both to another place, like FullTextFunction.

}

try {
matchPhraseQueryOptions();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the resolveOptions function could use a refactor - because most of it is duplicated in Match, MultiMatch, QueryString and here. But I am okay with doing that as a follow up.

failures.add(
Failure.fail(
mp.field(),
"[{}] {} cannot operate on [{}], which is not a field from an index mapping",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's get some tests for this particular case in VerifierTests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Analytics/ES|QL AKA ESQL >enhancement :SearchOrg/Relevance Label for the Search (solution/org) Relevance team Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) Team:Search - Relevance The Search organization Search Relevance team Team:SearchOrg Meta label for the Search Org (Enterprise Search) v9.1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants